package br.requisiteworks.requisito.modelo.service;

import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import br.requisiteworks.requisito.modelo.AtributoRequisito;
import br.requisiteworks.requisito.modelo.AtributoTipoRequisito;
import br.requisiteworks.requisito.modelo.TipoRequisito;
import br.requisiteworks.requisito.modelo.dao.AtributoRequisitoDao;
import br.requisiteworks.requisito.modelo.dao.AtributoTipoRequisitoDao;
import br.requisiteworks.util.persistencia.ErroBancoDados;
import br.requisiteworks.util.persistencia.ResultadoVazio;

@Service
public class AtributoTipoRequisitoService {

	/**
	 * Log da classe
	 */
	private static final Log log = LogFactory
			.getLog(AtributoTipoRequisitoService.class);

	@Autowired
	private AtributoTipoRequisitoDao atributoTipoRequisitoDao;

	@Autowired
	private AtributoRequisitoDao atributoRequisitoDao;

	/**
	 * Salva um novo {@link AtributoTipoRequisito} ao repositorio de dados
	 * 
	 * @param atributoTtipoRequisito
	 *            o {@link AtributoTipoRequisito} a ser adicionado ao
	 *            repositorio
	 * @throws ErroBancoDados
	 *             Caso ocorra algum erro durante a persistencia do
	 *             {@link AtributoTipoRequisito}
	 */
	public void salvarAtributoTipoRequisito(
			AtributoTipoRequisito atributoTipoRequisito) throws ErroBancoDados {
		this.atributoTipoRequisitoDao.insert(atributoTipoRequisito);
		log.info("Atributo de requisito adicionado com sucesso: "
				+ atributoTipoRequisito);
	}

	/**
	 * Atualiza um {@link TipoRequisito} existente no repositorio de dados
	 * 
	 * @param atributoTtipoRequisito
	 *            o {@link TipoRequisito} a ser atualizado
	 * @throws ErroBancoDados
	 *             Caso ocorra algum erro durante a persistencia do
	 *             {@link TipoRequisito}
	 */
	public void atualizarAtributoTipoRequisito(
			AtributoTipoRequisito atributoTipoRequisito) throws ErroBancoDados {
		this.atributoTipoRequisitoDao.update(atributoTipoRequisito);
		log.info("Atributo de requisito atualizado com sucesso: "
				+ atributoTipoRequisito);
	}

	/**
	 * Busca no repositorio por todos os {@link TipoRequisito}s cadastrados no
	 * sistema
	 * 
	 * @throws ResultadoVazio
	 *             Caso nenhum {@link TipoRequisito} seja encontrado
	 */
	public List<AtributoTipoRequisito> listarTipoRequisito()
			throws ResultadoVazio {
		return this.atributoTipoRequisitoDao.select();
	}

	/**
	 * Busca no repositorio um {@link TipoRequisito} cujo numero seja igual ao
	 * parametro passado
	 * 
	 * @param numero
	 *            O numero de identificacao do {@link TipoRequisito} no
	 *            repositorio de dados
	 * @throws ResultadoVazio
	 *             Caso um {@link TipoRequisito} nao seja encontrado
	 */
	public AtributoTipoRequisito carregarTipoRequisito(int numero)
			throws ResultadoVazio {
		return this.atributoTipoRequisitoDao.select(numero);
	}

	/**
	 * Remove do repositorio o {@link TipoRequisito} passado pelo parametro
	 * 
	 * @param atributoTtipoRequisito
	 *            O {@link TipoRequisito} que sera removido do repositorio de
	 *            dados
	 * @throws ErroBancoDados
	 *             Caso ocorra algum erro durante a transacao
	 */
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void deletaAtributoTipoRequisito(
			AtributoTipoRequisito atributoTipoRequisito) throws ErroBancoDados {

		try {
			List<AtributoRequisito> atributos = this.atributoRequisitoDao
					.select(atributoTipoRequisito);

			for (AtributoRequisito atributo : atributos) {
				this.atributoRequisitoDao.delete(atributo);
			}
		} catch (ResultadoVazio rv) {

		}

		this.atributoTipoRequisitoDao.delete(atributoTipoRequisito);
		log.info("Atributo de requisito apagado com sucesso: "
				+ atributoTipoRequisito);
	}

	public List<AtributoTipoRequisito> procuraNome(String nome)
			throws ResultadoVazio {
		return this.atributoTipoRequisitoDao.select(nome);
	}
}
